﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using XNALibrary.Interfaces;

namespace XNALibrary.Effects
{
    public class JonCustomEffect : CustomEffect
    {
        #region Variables

        private Texture2D m_ColorTexture;
        private Texture2D m_GlossMapTexture;
        public bool Discard{get;set;}

        #endregion

        #region Constructor

        public JonCustomEffect(Effect oEffect, Texture2D ColorTexture, Texture2D GlossMapTexture)
            : base(oEffect)
        {
            m_ColorTexture = ColorTexture;
            m_GlossMapTexture = GlossMapTexture;
            Discard = true;
            SetupParameters();
        }

        #endregion 

        #region Override Methods

        public override void SetupParameters()
        {
            if (CustEffect != null)
            {
                //Vector4 vColorDiffuse = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
                Vector4 vColorSpecular = new Vector4(1.0f, 1.0f, 0.0f, 1.0f);
                Vector4 vColorAmbient = new Vector4(0.1f, 0.1f, 0.1f, 1.0f);
                //Vector4 vLightDirection = new Vector4(0.0f, 0.0f, 1.0f, 1.0f);

                //CustEffect.Parameters["vecLightDir"].SetValue(vLightDirection);
                //CustEffect.Parameters["vDiffuseColor"].SetValue(vColorDiffuse);
                CustEffect.Parameters["vSpecularColor"].SetValue(vColorSpecular);
                CustEffect.Parameters["vAmbient"].SetValue(vColorAmbient);
                CustEffect.Parameters["GlossMap"].SetValue(m_GlossMapTexture);
                CustEffect.Parameters["ColorMap"].SetValue(m_ColorTexture);
                CustEffect.Parameters["vDiscard"].SetValue(Discard);
            }
        }

        public override void Update()
        {
        }

        public override void DrawEffect(RigidBody body, RenderControl rc)
        {
            Vector3 CamPos = rc.CurrentCamera.GetPosition();
            Matrix view = rc.CurrentCamera.View;
            Matrix projection = rc.CurrentCamera.Projection;
            GraphicsDevice device = rc.graphicsDevice;
            ModelMesh mesh;
            ModelMeshPart meshPart;
            Model model = body.Model;

            mesh = model.Meshes[0];
            meshPart = mesh.MeshParts[0];

            // set the vertex source to the mesh's vertex buffer
            device.Vertices[0].SetSource(
                mesh.VertexBuffer, meshPart.StreamOffset, meshPart.VertexStride);

            // set the vertex declaration
            device.VertexDeclaration = meshPart.VertexDeclaration;

            // set the current index buffer to the sample mesh's index buffer
            device.Indices = mesh.IndexBuffer;

            device.RenderState.CullMode = CullMode.None;

            Vector4 vecEye = new Vector4(CamPos.X, CamPos.Y, CamPos.Z, 0);

            CustEffect.Parameters["matWorldViewProj"].SetValue(body.GetWorld(mesh) * view * projection);
            CustEffect.Parameters["matWorld"].SetValue(body.GetWorld(mesh));
            CustEffect.Parameters["vecEye"].SetValue(vecEye);

            IPointLight[] lights = rc.GetLights(body.Position, 4);
            switch (lights.Length)
            {
                case 4:
                    //Light 4
                    effect.Parameters["Light4Enabled"].SetValue(lights[3].IsOn);
                    effect.Parameters["LightPos4"].SetValue(lights[3].Position);
                    effect.Parameters["LightPower4"].SetValue(lights[3].Intensity);
                    effect.Parameters["Color4"].SetValue(lights[3].Color.ToVector4());
                    goto Light3;

                case 3:
                    //Light 3
                    effect.Parameters["Light4Enabled"].SetValue(false);
                Light3:
                    //Light 3
                    effect.Parameters["Light3Enabled"].SetValue(lights[2].IsOn);
                    effect.Parameters["LightPos3"].SetValue(lights[2].Position);
                    effect.Parameters["LightPower3"].SetValue(lights[2].Intensity);
                    effect.Parameters["Color3"].SetValue(lights[2].Color.ToVector4());
                    goto Light2;

                case 2:
                    effect.Parameters["Light4Enabled"].SetValue(false);
                    effect.Parameters["Light3Enabled"].SetValue(false);
                Light2:
                    //Light 2
                    effect.Parameters["Light2Enabled"].SetValue(lights[1].IsOn);
                    effect.Parameters["LightPos2"].SetValue(lights[1].Position);
                    effect.Parameters["LightPower2"].SetValue(lights[1].Intensity);
                    effect.Parameters["Color2"].SetValue(lights[1].Color.ToVector4());
                    goto Light1;

                case 1:
                    effect.Parameters["Light4Enabled"].SetValue(false);
                    effect.Parameters["Light3Enabled"].SetValue(false);
                    effect.Parameters["Light2Enabled"].SetValue(false);
                Light1:
                    //Light 1
                    effect.Parameters["Light1Enabled"].SetValue(lights[0].IsOn);
                    effect.Parameters["LightPos1"].SetValue(lights[0].Position);
                    effect.Parameters["LightPower1"].SetValue(lights[0].Intensity);
                    effect.Parameters["Color1"].SetValue(lights[0].Color.ToVector4());

                    //If there are lights, Enable Lighting
                    effect.Parameters["LightEnabled"].SetValue(true);
                    break;

                case 0:
                    effect.Parameters["LightEnabled"].SetValue(false);
                    break;
            }

            CustEffect.Begin();
            foreach (EffectPass pass in CustEffect.CurrentTechnique.Passes)
            {
                pass.Begin();
                device.DrawIndexedPrimitives(
                PrimitiveType.TriangleList, meshPart.BaseVertex, 0,
                meshPart.NumVertices, meshPart.StartIndex, meshPart.PrimitiveCount);
                pass.End();
            }
            CustEffect.End();

            device.RenderState.CullMode = CullMode.CullCounterClockwiseFace;
        }

        #endregion

    }
}
